home *** CD-ROM | disk | FTP | other *** search
-
- {* Stack Research string for turbo pascal unit *}
- {* Public Domain, 21/07/94 by Mark Gauthier. *}
- {* Fidonet 1:242/818.5, FM 101:190/805.5 *}
-
- Unit Search;
-
- { What for?, it use stack function to search for a matching string
- in an array. }
-
- Interface
-
- Const
-
- MaxString : Word = 4096;
- MaxStack : Word = 500;
-
- Var
- StrAddr : Array[1..4096] of Pointer;
- { Addresse for all strings. }
-
- TotalStr : Word;
- { Curent strings number }
-
- StrFreq : Array[1..4096] of Word;
- { Search frequence for each string }
-
- procedure ClearAllStack;
- { Clear stack. You must call this procedure to tell unit
- you will change the searchstring. }
-
- procedure AddString (S:String);
- { Add a string in array, only if totalstr if < maxstring. }
-
- function SearchString (S:String) : boolean;
- { Search for a string, if stack is not clear previous search as
- been made. Example: you search for 'ABC' and this function
- return true. If you search for 'ABCD' then this function
- will go in stack and get all the old addr for 'ABC' and see
- if 'D' is the next letter for the check strings.
-
- * This unit is usefull to build compression unit.
- }
-
- implementation
-
- Var
- SearchStr : Pointer;
- LastFound : Word;
- CurentStack : Byte;
- StackPos : Array[1..2] of Word;
- StackData : Array[1..2,1..500] of Word;
-
- {*===================================================================*}
-
- { Return true is stack is empty }
- function StackIsEmpty:boolean;
- begin
- StackIsEmpty := false;
- if StackPos[CurentStack] = 0 then StackIsEmpty := true;
- end;
-
- {*===================================================================*}
-
- { Pop an element from stack }
- function MgPop:Word;
- begin
- MgPop := 0;
- If Not StackIsEmpty then
- begin
- MgPop := StackData[CurentStack, StackPos[CurentStack]];
- Dec(StackPos[CurentStack]);
- end;
- end;
-
- {*===================================================================*}
-
- { Push an element on stack }
- procedure MgPush(Number:word);
- var x:byte;
- begin
- if CurentStack = 1 then x := 2 else x := 1;
- If StackPos[x] < MaxStack then
- begin
- Inc(StackPos[x]);
- StackData[x, StackPos[x]] := Number;
- end;
- end;
-
- {*===================================================================*}
-
- { Clear the curent stack }
- procedure ClearStack;
- begin
- StackPos[CurentStack] := 0;
- end;
-
- {*===================================================================*}
-
- { Inverse pop and push stack }
- procedure InverseStack;
- begin
- ClearStack;
- If CurentStack = 1 then CurentStack := 2 else CurentStack := 1;
- end;
-
- {*===================================================================*}
-
- { Compare SearchStr(global var) and DATA(parameter) }
- {$F+}
- function Compare(Data:Pointer):boolean;assembler;
- asm
- push bp
- mov bp,sp
-
- push ds
-
- lds si,SearchStr
- lodsb
- mov cl,al
- mov ch,0
-
- les di,[Bp+8]
- inc di
-
- mov al,0
- cld
- repe cmpsb
- jne @NotMatch
- mov al,1
-
- @NotMatch:
-
- pop ds
- pop bp
- end;
- {$F-}
-
- {*===================================================================*}
-
- { Search procedure execute this procedure if stack is not empty. }
- function SearchWhitPop:boolean;
- Var Start : Word;
- begin
- SearchWhitPop := false;
- While not StackIsEmpty do
- begin
- Start := MgPop;
- if Compare(StrAddr[Start]) then
- begin
- LastFound := Start;
- SearchWhitPop := true;
- MgPush(Start);
- Inc(StrFreq[Start]);
- end;
- end;
- InverseStack;
- end;
-
- {*===================================================================*}
-
- { Search procedure execute this procedure if stack is empty. }
- function CompleteSearchPush:boolean;
- var i : word;
- begin
- CompleteSearchPush := false;
- For i := 1 to TotalStr do
- begin
- if Compare(StrAddr[i]) then
- begin
- LastFound := i;
- CompleteSearchPush := true;
- MgPush(i);
- Inc(StrFreq[i]);
- end;
- end;
- InverseStack;
- end;
-
- {*===================================================================*}
-
- { Public Search routine }
- function SearchString(S:String):boolean;
- begin
- SearchStr := Addr(S);
- If StackIsEmpty
- then SearchString := CompleteSearchPush
- else SearchString := SearchWhitPop;
- end;
-
- {*===================================================================*}
-
- { Add a string in heap }
- procedure AddString(S:String);
- begin
- Inc(TotalStr);
- GetMem(StrAddr[TotalStr], Length(S));
- Move(S,StrAddr[TotalStr]^, Length(S)+1);
- end;
-
- {*===================================================================*}
-
- { Clear pop and push stack }
- procedure ClearAllStack;
- begin
- InverseStack;
- ClearStack;
- end;
-
- {*===================================================================*}
-
- { Unit Initialisation }
- var i : word;
- Begin
- TotalStr := 0;
- CurentStack := 0;
- StackPos[1] := 0;
- StackPos[2] := 0;
- for i := 1 to 4096 do StrFreq[i] := 0;
- End.